<template>
  <div v-if="innerDialogFormVisible" class="ExperimentTemplateEditForm">
    <el-dialog
      v-toggle-full="resetTableWidth"
      class="base-dialog"
      :custom-class="'panna-dialog_big'"
      :append-to-body="true"
      :title="formData.templateName"
      align="center"
      :destroy-on-close="true"
      :close-on-click-modal="false"
      :before-close="beforeClose"
      :visible.sync="innerDialogFormVisible"
    >
      <el-container class="Experiment-edit-form-container">
        <el-aside
          width="278px"
          class="Experiment-edit-form-container_aside left"
        >
          <ElnTemplateSide
            ref="ElnTemplateSide"
            :form-data="formData"
            :page-view-mode="pageViewMode"
            :readonly="readonly"
            :show-field-label="showFieldLabel"
            :left-data="leftData"
            @setTagConfig="setTagConfig"
          />
        </el-aside>
        
        <el-main class="Experiment-edit-form-container_main">
          <BaseLoading v-if="loading" :loading-text="loadText" />
          <div v-if="startLoad" class="container_main-target">
            <draggable
              v-bind="{
                group: { name: 'drag', pull: false },
              }"
              :handle="targetMoveClass"
              class="target-card"
              style="height: 100%"
              @start="targetStart"
              @end="targetEnd"
            >
              <div
                v-for="item in targetList"
                :key="item.id"
                class="target-card-item"
                :class="{
                  design: pageViewMode === 'design',
                  preview: pageViewMode === 'preview' || readonly,
                }"
                :style="{ width: item.span === 12 ? '50%' : '100%' }"
              >
                <div v-show="showFieldLabel" class="card-field-label">
                  <span>{</span>
                  <span>{{ item.id }}</span>
                  <span>}</span>
                </div>
                <component
                  :is="item.name"
                  :ref="item.name"
                  class="card-item"
                  :params="item"
                  :page-view-mode="pageViewMode"
                  :readonly="readonly"
                  @deleteTargetControl="deleteTargetControl"
                  @changeMoveHandle="changeMoveHandle"
                  @tableLoadHandle="tableLoadHandle"
                  @tagValue2Select="tagValue2Select"
                ></component>
              </div>
            </draggable>
          </div>
        </el-main>
        <el-aside
          v-if="pageViewMode === 'design'"
          width="264px"
          class="Experiment-edit-form-container_aside right"
        >
          <div class="container_aside-source" :class="{ readonly: readonly }">
            <draggable
              v-model="sourceList"
              v-bind="{
                group: { name: 'drag', pull: 'clone' },
                sort: false,
              }"
              :handle="sourceMoveClass"
              class="source-dragArea"
              @end="optionEnd"
            >
              <div
                v-for="item in sourceList"
                :key="item.controlType"
                :style="{
                  background: `url(${require('../../../img/' +
                    item.controlType.toLowerCase() +
                    '-bgc.png')}) no-repeat 100% 100%`,
                }"
                class="source-dragArea-item"
              >
                <img
                  :src="
                    require('../../../img/' +
                      item.controlType.toLowerCase() +
                      '-icon.png')
                  "
                />
                <span class="source-dragArea-item-handle">
                  {{ item.label }}
                </span>
              </div>
            </draggable>
          </div>
        </el-aside>
      </el-container>
      <div slot="footer" class="dialog-footer" align="center">
        <el-button v-if="!readonly" class="footer-save" @click="save('save')">
          <span>保存</span>
        </el-button>
        <el-button
          v-if="!readonly"
          class="footer-saveandclose"
          @click="save('close')"
        >
          <span>保存并关闭</span>
        </el-button>
        <el-button v-if="!readonly" class="footer-preview" @click="preview">
          <span>{{ pageViewMode !== "preview" ? "预览" : "取消预览" }}</span>
        </el-button>
        <el-button
          v-if="readonly"
          class="footer-saveandclose"
          @click="lookFieldLabel"
        >
          <span>
            {{ showFieldLabel ? "取消查看字段标签" : "查看字段标签" }}
          </span>
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getList as getFormConfig } from "../../../api/Eln/ElnComponent.js";
import {
  getSingleList,
  create,
  update,
} from "../../../api/Eln/ExperimentTemplate.js";
import draggable from "vuedraggable";
import { deepClone } from "../../../utils";
import ElnTemplateSide from "../Components/ElnTemplateSide.vue";
const allComponents = require.context(
  "../../../components/BaseControl",
  true,
  /\.vue$/
);
const res_components = {};
allComponents.keys().forEach((item) => {
  const comp = allComponents(item);
  const name = comp.default.name;
  res_components[name] = comp.default;
});
export default {
  components: { draggable, ElnTemplateSide, ...res_components },
  props: {
    dialogFormVisible2: {
      type: Boolean,
      default: false,
    },
    readonly: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      targetMoveClass: ".control-title",
      sourceMoveClass: ".source-dragArea-item",
      innerDialogFormVisible: false,
      startLoad: false,
      loading: false,
      loadText: "",
      hadSave: false,
      pageViewMode: "design", // runtime 运行时 design 设计时 pageview 预览
      showFieldLabel: false,
      formLabelWidth: "70px",
      defaultValueJSONType: [
        "Radio",
        "Select",
        "Checkbox",
        "MultipleSelect",
        "Table",
        "DatePicker",
      ],
      valueJSONType: [
        "Radio",
        "Select",
        "Checkbox",
        "MultipleSelect",
        "Table",
        "Image",
      ],
      sendTemplate: "",
      pagination: {
        Type: 0,
        PageIndex: 0,
        PageSize: 999,
      },
      sourceList: [],
      targetList: [],
      formData: {
        templateName: "",
        templateCode: "",
        sampleCategoryName: "",
        articleNumber: "",
        creatorTime: "",
        creatorName: "",
        tableDetectionItemAll: [],
      },
      errorMsg: {
        templateName: "",
        templateCode: "",
        sampleCategoryName: "",
        articleNumber: "",
        creatorTime: "",
        creatorName: "",
      },
      leftData: [],

      tableLen: 0, // 表格个数

      tagConfig: {},
    };
  },
  watch: {
    dialogFormVisible2(val) {
      this.innerDialogFormVisible = val;
      if (this.readonly) {
        this.targetMoveClass = this.sourceMoveClass = ".asdhias";
      } else {
        this.targetMoveClass = ".control-title";
        this.sourceMoveClass = ".source-dragArea-item";
      }
      val && this.init();
    },
    innerDialogFormVisible(val) {
      this.$emit("update:dialogFormVisible2", val);
    },
  },
  destroyed() {
    // window.removeEventListener("mousewheel", this.closeLuckySheetFn);
  },
  created() {
    this.$root.$on("deleteTargetControl", this.deleteTargetControl);
    // window.addEventListener("mousewheel", this.closeLuckySheetFn);
  },
  methods: {
    init() {
      this.tableLen = 0;
      this.hadSave = false;
      this.startLoad = false;
      // 前端定义数据数据
      if (
        !Object.prototype.hasOwnProperty.call(this.formData, "articleNumber")
      ) {
        this.formData.articleNumber = "";
        this.formData.creatorTime = "";
        this.formData.creatorName = "";
      }
      this.formData.experimentNumber = this.formData.templateCode;
      const promiseList = [this.getFormConfig()];
      if (this.formData.id > 0) {
        promiseList.push(this.getList());
      } else {
        this.startLoad = true;
      }
      Promise.all(promiseList);
    },
    // 获取右侧控件配置信息
    getFormConfig() {
      getFormConfig(this.pagination).then((res) => {
        if (!res || !res.data.dataList.length) return;
        this.sourceList = [];
        res.data.dataList.forEach((list) => {
          const content = JSON.parse(list.content);
          content.placeholder = "";
          content.name = `Control${content.controlType}`;
          this.sourceList.push(content);
        });
      });
    },
    // 获取中间数据
    getList() {
      this.loading = true;
      this.loadText = "加载中...";
      getSingleList({ Id: this.formData.id }).then((res) => {
        if (!res.data.templateContentDto) {
          this.loading = false;
          this.startLoad = true;
          return;
        }
        const JPTemplate = (this.sendTemplate = res.data.templateContentDto);
        this.leftData = JPTemplate.leftData;
        // let isExisTable = false;
        this.targetList = JPTemplate.centerData.filter((x) => {
          if (x.controlType === "Table") {
            this.tableLen++;
            x.required = false;
            // if (isExisTable) return false;
            // else {
            //   isExisTable = true;
            //   return true;
            // }
          }
          return x && x.controlType !== "Title";
        });
        this.targetList.forEach((item) => {
          item.placeholder = "";
          item.name = `Control${item.controlType}`;
          if (item.value && this.valueJSONType.includes(item.controlType)) {
            item.value = JSON.parse(item.value);
          }
          if (
            item.defaultValue &&
            this.defaultValueJSONType.includes(item.controlType)
          ) {
            item.defaultValue = JSON.parse(item.defaultValue);
          }
        });
        this.startLoad = true;
        if (this.tableLen === 0) this.loading = false;
        else this.loadText = "表格加载中...";
      });
    },
    // 删除目标控件
    deleteTargetControl(id) {
      this.targetList = this.targetList.filter((x) => x.id !== id);
      for (let i = 0; i < this.formData.tableDetectionItemAll.length; i++) {
        var data = this.formData.tableDetectionItemAll[i];
        if (data.tableId === id) {
          this.formData.tableDetectionItemAll[i].dataPositioning = "";
          this.formData.tableDetectionItemAll[i].tableId = "0";
          this.formData.tableDetectionItemAll[i].tableName = "";
          this.formData.tableDetectionItemAll[i].title = "";
          this.formData.tableDetectionItemAll[i].resultColumn = -1;
          this.formData.tableDetectionItemAll[i].resultRow = -1;
        }
      }
    },
    // 预览
    preview() {
      this.pageViewMode =
        this.pageViewMode === "preview" ? "design" : "preview";

      this.targetMoveClass =
        this.pageViewMode !== "design" || this.readonly
          ? ".ajsdad"
          : ".card-item";
    },
    // 保存
    async save(close) {
      const saveList = new Array(this.targetList.length).fill(null);
      let isOptionsNull = false;
      const promiseTable = [];
      for (const i in this.$refs) {
        if (i === "formData") continue;
        const tempRef = this.$refs[i];
        if (!Array.isArray(tempRef) || !tempRef.length) continue;
        tempRef.forEach((ref) => {
          if (ref.validate instanceof Function) {
            const refData = ref.validate();
            if (refData instanceof Promise) {
              promiseTable.push(refData);
              return;
            }
            const { controlValue } = deepClone(refData);
            // 删除多余的参数
            // delete controlValue.design;
            delete controlValue.name;
            // 修改特定控件value&defaultValue数据格式
            controlValue.data = controlValue.data.filter((x) => x.label !== "");
            // 判断选项控件是否存在选择项
            ["Checkbox", "Radio", "Select", "MultipleSelect"].includes(
              controlValue.controlType
            ) &&
              controlValue.data.length === 0 &&
              (isOptionsNull = controlValue);
            // 格式化特殊控件的value以及defaultValue值
            controlValue.value &&
              this.valueJSONType.includes(controlValue.controlType) &&
              (controlValue.value = JSON.stringify(controlValue.value));
            controlValue.defaultValue &&
              this.defaultValueJSONType.includes(controlValue.controlType) &&
              (controlValue.defaultValue = JSON.stringify(
                controlValue.defaultValue
              ));
            const currentIdx = this.targetList.findIndex(
              (x) => x.id === controlValue.id
            );
            saveList.splice(currentIdx, 1, controlValue);
          }
        });
        if (isOptionsNull) break;
      }
      // 处理table的异步数据问题
      if (promiseTable.length) {
        const tableData = await Promise.all(promiseTable);
        tableData.forEach((x) => {
          const { controlValue } = deepClone(x);
          const currentIdx = this.targetList.findIndex(
            (v) => v.id === controlValue.id
          );
          controlValue.value &&
            (controlValue.value = JSON.stringify(controlValue.value));
          controlValue.defaultValue &&
            (controlValue.defaultValue = JSON.stringify(
              controlValue.defaultValue
            ));
          saveList.splice(currentIdx, 1, controlValue);
        });
      }

      if (isOptionsNull) {
        this.$message.error(`请保证${isOptionsNull.label}至少存在一个选择项`);
        return;
      }

      const leftData = [];
      for (const i in this.formData) {
        this.getLeftTemplate(i) && leftData.push(this.getLeftTemplate(i));
      }
      this.sendTemplate = {
        leftData: leftData,
        centerData: saveList,
      };
      const operateType = this.formData.id > 0 ? update : create;
      const params = deepClone(this.formData);
      this.formData.id <= 0 && delete params.id;
      params.templateContentDto = this.sendTemplate;
      operateType(params).then((res) => {
        this.hadSave = true;
        this.formData.id = res.data?.id;
        close === "close" && this.closeDialog();
        this.$parent.closeDialog(close);
      });
    },
    // 查看字段标签
    lookFieldLabel() {
      this.showFieldLabel = !this.showFieldLabel;
    },
    getLeftTemplate(code) {
      const tempDict = {
        // templateName: { type: "Text", label: "模板名称" },
        templateCode: { type: "Text", label: "记录编号" },
        // sampleCategoryName: { type: "Select", label: "样品类别" },
        // articleNumber: { type: "Text", label: "品号" },
        creatorTime: { type: "DatePicker", label: "开展时间" },
        creatorName: { type: "Text", label: "检测人" },
      };
      if (!tempDict[code]) return;
      const returnObj = {
        code,
        label: tempDict[code].label,
        controlType: tempDict[code].type,
        required: true,
        placeholder: `请输入${tempDict[code].label}`,
        defaultValue: "",
        multiple: false,
        unit: "",
        value: ["sampleCategoryName"].includes(code)
          ? "" // this.formData["experimentSampleCategorys"].map(x => x.id).join(",")
          : this.formData[code],
        data:
          // code === "sampleCategoryName"
          //   ? this.formData.experimentSampleCategorys
          //   :
          code === "detectionItemName"
            ? this.formData.experimentDetectionItems
            : [],
      };
      if (code === "creatorTime") {
        returnObj["dateType"] = "Date";
        returnObj["defaultValue"] = JSON.stringify({
          type: "nowDate",
          date: "",
        });
      }
      if (code === "creatorName") returnObj["value"] = "";
      return returnObj;
    },
    closeDialog() {
      this.targetList = [];
      this.pageViewMode = "design";
      this.showFieldLabel = false;
      this.hadSave &&
        this.$emit("sendTemplate", {
          templateContentDto: this.sendTemplate,
          id: this.formData.id,
        });
      this.innerDialogFormVisible = false;

      // this.closeLuckySheetFn();
    },
    beforeClose(done) {
      this.closeDialog();
      done();
    },
    // 表格加载完成事件
    tableLoadHandle() {
      this.tableLen--;
      if (this.tableLen === 0) this.loading = false;
    },
    tagValue2Select(param) {
      // 讲最终值信息返回给side组件
      this.$refs.ElnTemplateSide.tagValue2Select instanceof Function &&
        this.$refs.ElnTemplateSide.tagValue2Select(param);

      // 更新当前表格之外表格的最终值
      this.$refs.ControlTable.forEach((x) => {
        if (x.newParams.id === param.id) return;
        x.sendTagConfig({ type: "reset", projectId: this.tagConfig.projectId });
      });
    },
    // 右侧拖拽结束事件
    optionEnd(ev) {
      // 如果拖拽目标区域和左侧区域的 name 一致，允许拖拽，并改变状态\
      if (ev.to.className === "target-card") {
        const newList = Object.assign({}, this.sourceList[ev.oldIndex]);
        if (
          newList.controlType === "Table" &&
          this.targetList.some((l) => l.controlType === "Table")
        ) {
          // return this.$message.warning("当前模板上表格控件已超出最大限制");
        }
        newList.id = new Date().getTime() + "";
        // newList.design = true;
        this.targetList.splice(ev.newIndex, 0, newList);
      }
    },
    // 左侧区域开始拖动事件（修改右侧区域的名字，不一致的话拖动失败）
    targetStart() {
      // this.optionsName = "1111";
    },
    // 拖动结束时，把右侧区域的名字恢复
    targetEnd(event) {
      const oldIndex = event.oldIndex; // 移动初始位置
      const newIndex = event.newIndex; // 运动终止位置
      const diff = Math.abs(newIndex - oldIndex); // 插值绝对值
      const index = this.targetList[oldIndex];
      if (oldIndex > newIndex) {
        for (let i = 0; i < diff; i++) {
          this.targetList[oldIndex - i] = this.targetList[oldIndex - i - 1];
        }
        this.targetList[newIndex] = index;
      } else {
        for (let i = 0; i < diff; i++) {
          this.targetList[oldIndex + i] = this.targetList[oldIndex + i + 1];
        }
        this.targetList[newIndex] = index;
      }
    },
    // 表格控件和其他控件挪动的区域不同
    changeMoveHandle(val) {
      this.targetMoveClass = this.readonly
        ? ".asjdhasd"
        : val
        ? ".control-title"
        : ".card-item";
    },
    closeLuckySheetFn() {
      // $(
      //   "#luckysheet-formula-functionrange .luckysheet-formula-functionrange-highlight"
      // ).remove();
      // $("#luckysheet-input-box").removeAttr("style");
      // $("#luckysheet-input-box-index").hide();
      // $(
      //   "#luckysheet-wa-functionbox-cancel, #luckysheet-wa-functionbox-confirm"
      // ).removeClass("luckysheet-wa-calculate-active");
      // $("#luckysheet-formula-functionrange-select").hide();
      // $("#luckysheet-row-count-show, #luckysheet-column-count-show").hide();
      // // $("#luckysheet-cols-h-selected, #luckysheet-rows-h-selected").hide();
      // $("#luckysheet-formula-search-c, #luckysheet-formula-help-c").hide();
    },
    resetTableWidth() {
      this.$refs.ControlTable?.length &&
        this.$refs.ControlTable.forEach((x) => {
          x.customFn();
        });
    },

    // 发送最终值配置到table
    setTagConfig(config) {
      this.tagConfig = config;
      this.$refs.ControlTable?.length &&
        this.$refs.ControlTable.forEach((x) => {
          x.sendTagConfig(config);
        });
    },
  },
};
</script>
<style lang="scss" scoped>
.Eln_flex {
  display: flex;
  align-items: center;
  align-content: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
}

// ::v-deep .eln-form.el-dialog {
//   height: 736px;
//   margin-top: 10vh !important;
// }
::v-deep .el-dialog__header {
  // padding: 23px !important;
  .el-dialog__title {
    height: 26px;
    font-size: 20px;
    font-family: "Microsoft YaHei";
    color: #232638;
    line-height: 26px;
  }
}

::v-deep .el-dialog__body {
  padding: 0 !important;
  height: calc(100% - 72px - 64px);
  overflow: auto;
  .Experiment-edit-form-container {
    height: 100%;

    .Experiment-edit-form-container_main {
      padding: 0 16px;

      & > .container_main-target {
        width: 100%;

        & > .target-card {
          min-height: 600px;
          padding-bottom: 18px;
          @extend .Eln_flex;
          justify-content: flex-start;

          & > .target-card-item {
            margin-top: 18px;
            cursor: move;

            & > .card-field-label {
              display: block;
              width: 100%;
              height: 16px;
              font-size: 0;
              text-align: left;
              margin-bottom: 6px;

              span {
                font-size: 12px;
                font-family: "Microsoft YaHei";
                color: #da1c76;
                line-height: 16px;
              }
            }

            // 各控件基础样式
            .control {
              display: flex;
              align-items: center;
              box-sizing: border-box;

              &.flex-start {
                align-items: flex-start;
              }

              &.image {
                align-items: flex-start;

                & > .control-title {
                  margin-top: 6px;
                }

                .control-operate {
                  margin-top: 4px;
                }
              }

              & > * {
                flex-shrink: 0;
              }

              & > .control-title {
                // width: 80px;
                height: 16px;
                font-size: 12px;
                font-family: "Microsoft YaHei";
                color: #666666;
                line-height: 16px;
                display: flex;
                align-items: center;
                justify-content: flex-end;

                & > .title-icon {
                  color: red;
                  padding-right: 3px;
                }

                & > .title-label {
                  text-align: right;
                  overflow: hidden;
                  text-overflow: ellipsis;
                  white-space: nowrap;
                }
              }

              .control-content {
                // width: calc(100% - 80px - 52px - 10px);
                flex: 1;
                margin-left: 10px;
              }
            }

            &.design {
              .card-item {
                min-height: 29px;
                &:hover {
                  .control-operate {
                    opacity: 1;
                    pointer-events: all;
                  }
                }
                & > .control-content {
                  .el-input .el-input__inner,
                  .el-textarea .el-textarea__inner {
                    border-color: #dcdfe6 !important;
                  }

                  .el-input.el-date-editor {
                    width: 100%;
                  }

                  .el-tag__close {
                    display: none;
                  }
                }

                .control-operate {
                  opacity: 0;
                  pointer-events: none;
                }
              }
            }

            &.preview {
              cursor: default !important;
              .card-item.control {
                min-height: 29px;
                .control-content {
                  flex: 1;
                  padding-right: 52px;

                  .el-input .el-input__inner,
                  .el-textarea .el-textarea__inner {
                    border-color: #dcdfe6 !important;
                  }

                  & > .el-select {
                    width: 100%;
                  }

                  .el-select {
                    .el-select__tags {
                      height: auto;

                      .el-tag__close {
                        display: none;
                      }
                    }
                  }
                }
              }
            }
          }

          & > .source-dragArea-item {
            background: none !important;
            border: 1px solid #eee;
            background-color: #fdfdfd !important;
            padding: 7px 15px !important;
            transform: scale(0.8) !important;
            justify-content: flex-start !important;

            & > img {
              display: none;
            }
          }
        }
      }
    }

    .Experiment-edit-form-container_aside {
      &.left {
        box-sizing: border-box;
        padding: 24px;
        background-color: #ecf0f7;
        overflow: hidden;
        overflow-y: auto;
      }
      &.right {
        background-color: #f1f4fa;
        box-sizing: border-box;
        padding: 0 40px;
        & > .container_aside-source {
          &.readonly > .source-dragArea > .source-dragArea-item {
            cursor: default !important;
          }
          & > .source-dragArea {
            @extend .Eln_flex;
            & > .source-dragArea-item {
              width: 80px;
              height: 28px;
              background: linear-gradient(45deg, #3a7efc 0%, #48a2f7 100%);
              border-radius: 4px;
              // border: 1px solid #76a6ff;
              margin-top: 30px;
              box-sizing: border-box;
              padding: 7px 9px;
              display: flex;
              align-items: center;
              align-content: flex-start;
              font-size: 0;
              cursor: move;

              & > .source-dragArea-item-handle {
                font-size: 12px;
                transform: scale(0.8);
                font-family: "Microsoft YaHei";
                color: #ffffff;
                line-height: 14px;
                height: 14px;
                margin-left: 1px;
              }
            }
          }
        }
      }
    }
  }

  .Experiment-edit-form-operate {
    background-color: #81d3f8;
    @extend .Eln_flex;
    align-content: center;
    width: 100%;
    height: 48px;
    position: absolute;
    left: 0;
    bottom: 0;
    box-sizing: border-box;
    padding: 0 28%;
  }
}
::v-deep .el-dialog__footer {
  padding: 18px !important;
  .dialog-footer {
    button {
      height: 28px;
      border-radius: 2px;
      border-radius: 2px;
      line-height: 8px;
      text-align: center;
      padding: 7px 23px;
      background: #3a7efc;
      border: none;

      & + .el-button {
        margin-left: 20px;
      }

      &:hover {
        background-color: #5792ff;
      }

      span {
        display: inline-block;
        height: 14px;
        line-height: 14px;
        span {
          font-size: 12px;
          font-family: "Microsoft YaHei";
          color: #ffffff;
          // transform: scale(0.8);
          // transform-origin: 0 0;
        }
      }
    }
    .footer-saveandclose {
      padding: 7px 15px;
      width: unset;
    }
    .footer-preview {
      width: unset;
      padding: 6px 22px;
      border: 1px solid #07c15f;
      background: #e7f6ee;

      &:hover {
        background-color: #07c15f;

        span {
          color: #ffffff;
        }
      }

      span {
        color: #07bf61;
      }
    }
  }
}
</style>
